<!DOCTYPE html>
<html lang="zh-cn">

<head>
    <meta charset="UTF-8">
    <title class="title">[文件管理器]</title>
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <style type="text/css">
        .content {background: transparent;}
        .btn {position: relative;top: 0;left: 0;bottom: 0;right: 0;}
        .btn .file {position: fixed;z-index: 93;left: 0;right: 0;top: 0;bottom: 0;width: 100%;opacity: 0;}
    </style>
</head>

<body>

<div id="content" class="content">
    <div class="btn">
        <input @change="onChange" :accept="accept" ref="file" class="file" type="file"/>
    </div>
</div>

<script type="text/javascript" src="js/vue.min.js"></script>
<script type="text/javascript">
    let _this;
    var vm = new Vue({
        el: '#content',
        data: {
            accept: '',
        },
        mounted() {

            console.log('加载webview');
            _this = this;
            this.files = new Map();
            document.addEventListener('plusready', (e)=>{
                let {debug,instantly,prohibited} = plus.webview.currentWebview();
                this.debug = debug;
                this.instantly = instantly;
                this.prohibited = prohibited;
                this.accept = prohibited.accept;
                location.href = 'callback?retype=updateOption';
            }, false);




        },
        methods: {
            toast(msg) {
                plus.nativeUI.toast(msg);
            },
            clear(name) {
                if (!name) {
                    this.files.clear();
                    return;
                }
                this.files.delete(name);
            },
            setData(option='{}') {
                this.debug&&console.log('更新参数：'+option);
                try{
                    _this.option = JSON.parse(option);
                }catch(e){
                    console.error('参数设置错误')
                }
            },
            async upload(name=''){
                if (name && this.files.has(name)) {
                    await this.createUpload(this.files.get(name));
                }
                else {
                    for (let item of this.files.values()) {
                        if (item.type === 'waiting' || item.type === 'fail') {
                            await this.createUpload(item);
                        }
                    }
                }
            },
            onChange(e) {
                let fileDom = this.$refs.file;
                let file = fileDom.files[0];
                let name = file.name;
                fileDom.value = '';
                this.debug&&console.log('文件名称',name,'大小',file.size);

                if (file) {
                    // 限制文件格式
                    let suffix = name.substring(name.lastIndexOf(".")+1).toLowerCase();
                    let formats = this.prohibited.formats.toLowerCase();
                    if (formats&&!formats.includes(suffix)) {
                        this.toast(`不支持上传${suffix.toUpperCase()}格式文件`);
                        return;
                    }
                    console.log('this.size',this.prohibited.size);
                    // 限制文件大小
                    if (file.size > 1024 * 1024 * Math.abs(this.prohibited.size)) {
                        this.toast(`附件大小请勿超过${this.prohibited.size}M`)
                        return;
                    }
                    let path = URL.createObjectURL(file);
                    this.files.set(file.name,{file,path,name: file.name,size: file.size,progress: 0,type: 'waiting'});
                    this.callChange();
                    this.instantly&&this.upload();
                }

            },
            /**
             * @returns {Map} 已选择的文件Map集
             */
            callChange() {
                location.href = 'callback?retype=change&files=' + escape(JSON.stringify([...this.files]));
            },
            /**
             * @returns {object} 正在处理的当前对象
             */
            changeFilesItem(item,end='') {
                this.files.set(item.name,item);
                location.href = 'callback?retype=progress&end='+ end +'&item=' + escape(JSON.stringify(item));
            },
            createUpload(item) {
                this.debug&&console.log('准备上传,option=：'+JSON.stringify(this.option));
                item.type = 'loading';
                delete item.responseText;
                return new Promise((resolve,reject)=>{
                    let {url,name,method='POST',header={},formData={}} = this.option;
                    let form = new FormData();
                    for (let keys in formData) {
                        form.append(keys, formData[keys])
                    }
                    form.append(name, item.file);
                    let xmlRequest = new XMLHttpRequest();
                    xmlRequest.open(method, url, true);
                    for (let keys in header) {
                        xmlRequest.setRequestHeader(keys, header[keys])
                    }
                    xmlRequest.upload.addEventListener(
                        'progress',
                        event => {
                            if (event.lengthComputable) {
                                let progress = Math.ceil((event.loaded * 100) / event.total)
                                if (progress <= 100) {
                                    item.progress = progress;
                                    this.changeFilesItem(item);
                                }
                            }
                        },
                        false
                    );

                    xmlRequest.ontimeout = () => {
                        console.error('请求超时')
                        item.type = 'fail';
                        this.changeFilesItem(item,true);
                        return resolve(false);
                    }

                    xmlRequest.onreadystatechange = ev => {
                        if (xmlRequest.readyState == 4) {
                            if (xmlRequest.status == 200) {
                                this.debug && console.log('上传完成：' + xmlRequest.responseText)
                                item['responseText'] = xmlRequest.responseText;
                                item.type = 'success';
                                this.changeFilesItem(item,true);
                                return resolve(true);
                            } else if (xmlRequest.status == 0) {
                                console.error('status = 0 :请检查请求头Content-Type与服务端是否匹配，服务端已正确开启跨域，并且nginx未拦截阻止请求')
                            }
                            console.error('--ERROR--：status = ' + xmlRequest.status)
                            item.type = 'fail';
                            this.changeFilesItem(item,true);
                            return resolve(false);
                        }
                    }
                    xmlRequest.send(form)
                });

            }
        }
    });

</script>
</body>

</html>
